#include "util/logger/LoggerManager.h"
#include "util/logger/ConsoleLogger.h"
#include "util/logger/FileLogger.h"
#include "util/StringUtils.h"
#include <stdio.h>

namespace util {

LoggerManager* LoggerManager::INSTANCE = NULL;

LoggerManager* LoggerManager::getInstance() {
	if (INSTANCE == NULL) {
		INSTANCE = new LoggerManager(false);
	}
	return INSTANCE;
}

LoggerManager* LoggerManager::getInstanceConfigSafe() {
	if (INSTANCE == NULL) {
		INSTANCE = new LoggerManager(true);
	}
	return INSTANCE;
}
LoggerManager::~LoggerManager() {
	INSTANCE = NULL;
}

LoggerManager::LoggerManager(bool onErrorBuildDefaultConsole) {
	FILE* configFile = fopen("res/logger.config", "r");
	bool error = false;
	std::string errorMessage;
	if (configFile != NULL && !ferror(configFile)) {
		std::string logType = this->readConfigFileLine(configFile);
		if (ferror(configFile) == 0) {
			if (logType.compare("console") == 0) {
				this->logger = new ConsoleLogger();
			} else if (logType.compare("file") == 0) {
				std::string logFileName = this->readConfigFileLine(configFile);
				std::string errorFileName =
						this->readConfigFileLine(configFile);
				if (ferror(configFile) == 0) {
					this->logger = new FileLogger(logFileName, errorFileName);
				} else {
					error = true;
					errorMessage
							= "ERROR en FileManager: hubo un error leyendo los nombres de archivos en el archivo \"res/logger.config\"";
				}
			} else {
				error = true;
				errorMessage
						= "ERROR en FileManager: no se especifico el tipo de logueo en el archivo \"res/logger.config\"";
			}
		} else {
			error = true;
			errorMessage
					= "ERROR en FileManager: error leyendo el archivo \"res/logger.config\"";
		}
		fclose(configFile);
	} else {
		error = true;
		errorMessage
				= "ERROR en FileManager: no se pudo abrir el archivo \"res/logger.config\"";
	}
	if (error) {
		printf("%s\n", errorMessage.c_str());
		if (onErrorBuildDefaultConsole) {
			printf("Se utilizara por defecto el logger a consola\n\n");
			this->logger = new ConsoleLogger();
		}
	}
}

Logger* LoggerManager::getLogger() {
	return this->logger;
}

std::string LoggerManager::readConfigFileLine(FILE* configFile) {
	char aux[255];
	char* info;
	std::string line = "";
	char c = '#';
	while (c == '#') {
		info = fgets(aux, 255, configFile);
		if (ferror(configFile) || feof(configFile)) {
			break;
		}
		line = info;
		char lineSeparator = '\n';
		if (line[line.size() - 1] == lineSeparator) {
			line = line.substr(0, line.length() - 1);
		}
		char separator = '\r';
		if (line[line.size() - 1] == separator) {
			line = line.substr(0, line.length() - 1);
		}
		trim(line);
		c = line[0];
	}
	return line;
}

}
